﻿using ZyGame.Sound;

namespace ZyGame
{
    using ZyGame.Avatar;
    using ZyGame.Datable;
    using ZyGame.Event;
    using ZyGame.Execute;
    using ZyGame.Files;
    using ZyGame.Game;
    using ZyGame.Resource;
    using ZyGame.Transport;
    using ZyGame.UI;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Object = UnityEngine.Object;
    using ZyGame.Cache;
    using static ZyGame.UnityHandler;
    using System.Threading.Tasks;
    using ZyGame.Transport.Common;
    using ZyGame.Transport.TCP;
    using ZyGame.Transport.UDP;
    using ZyGame.Transport.Web;

    public static class Client
    {
        /// <summary>
        /// 音效管理
        /// </summary>
        public sealed class Music
        {
            /// <summary>
            /// 播放音效
            /// </summary>
            /// <param name="name"></param>
            /// <param name="isLoop"></param>
            public static void PlaySound(string name, bool isLoop = false)
                => SoundManager.instance.PlaySound(name, isLoop);

            /// <summary>
            /// 播放音效
            /// </summary>
            /// <param name="name"></param>
            public static void PlayEffectSound(string name, bool isLoop = false)
                => SoundManager.instance.PlayEffectSound(name, isLoop);

            /// <summary>
            /// 播放一次
            /// </summary>
            /// <param name="name"></param>
            public static void PlayOneShort(string name)
                => SoundManager.instance.PlaySound(name, false);

            /// <summary>
            /// 播放一次音效
            /// </summary>
            /// <param name="name"></param>
            public static void PlayOneShortEffectSound(string name)
                => SoundManager.instance.PlayEffectSound(name, false);

            /// <summary>
            /// 停止播放
            /// </summary>
            /// <param name="name"></param>
            public static void Stop(string name)
                => SoundManager.instance.StopPlay(name);

            /// <summary>
            /// 停止播放
            /// </summary>
            /// <param name="name"></param>
            public static void StopAll()
                => SoundManager.instance.StopAllPlay();


            /// <summary>
            /// 获取音乐音量
            /// </summary>
            /// <returns></returns>
            public static float GetSoundVolument()
                => SoundManager.instance.GetSoundVolument();

            /// <summary>
            /// 获取音效音量
            /// </summary>
            /// <returns></returns>
            public static float GetEffectSoundVolument()
                => SoundManager.instance.GetEffectSoundVolument();

            /// <summary>
            /// 设置音乐音量
            /// </summary>
            /// <param name="volument"></param>
            public static void SetSoundVolument(float volument)
                => SoundManager.instance.SetSoundVolument(volument);

            /// <summary>
            /// 设置音效音量
            /// </summary>
            /// <param name="volument"></param>
            public static void SetEffectSoundVolument(float volument)
                => SoundManager.instance.SetEffectSoundVolument(volument);

            /// <summary>
            /// 重新开始播放音乐
            /// </summary>
            public static void ResumeSound() => SoundManager.instance.ResumeSound();

            /// <summary>
            /// 重新开始播放音效
            /// </summary>
            public static void ResumeEffectSound() => SoundManager.instance.ResumeEffectSound();

            /// <summary>
            /// 全部重新开始
            /// </summary>
            public static void ResumeAll() => SoundManager.instance.ResumeAll();
        }

        /// <summary>
        /// 缓存器
        /// </summary>
        public sealed class Cache
        {
            public static void Enqueue(IDatable context)
                => DataCacheing.instance.Enqueue(context);

            public static bool TryDequeue<T>(string name, out T result) where T : IDatable
                => DataCacheing.instance.TryGetAndRemove(name, out result);

            public static bool TryDequeue<T>(Func<T, bool> func, out T result) where T : class, IDatable
                => DataCacheing.instance.TryGetAndRemove(func, out result);
        }

        /// <summary>
        /// 数据表
        /// </summary>
        public sealed class Datable
        {
            public static T GetDatable<T>() where T : IDatable
                => DatableManager.instance.GetDatable<T>(typeof(T).Name);

            public static T GetDatable<T>(string name) where T : IDatable
                => DatableManager.instance.GetDatable<T>(name);

            public static void Remove<T>() where T : IDatable
                => DatableManager.instance.Remove<T>(string.Empty);

            public static void Remove<T>(string name) where T : IDatable
                => DatableManager.instance.Remove<T>(name);

            public static string GetUserCacheData(string cacheName)
                => DatableManager.instance.GetUserDatable(cacheName);

            public static void UpdateUserCacheData(string cacheName, string datable)
                => DatableManager.instance.SetUserDatable(cacheName, datable);
        }

        /// <summary>
        /// 多语言
        /// </summary>
        public sealed class Language
        {
            public static void Options(string language_Type)
                => LanguageSetting.LanguageOptions(language_Type);

            public static string Get(int id)
                => LanguageSetting.instance.Get(id);
        }

        /// <summary>
        /// 
        /// </summary>
        public sealed class Game
        {
            public static void Initialized()
                => WorldManager.instance.Initialized();

            /// <summary>
            /// 加载子游戏模块
            /// </summary>
            /// <param name="gameid"></param>
            /// <param name="name"></param>
            public static void LoadSubGame(int gameid, string entryMethod, params object[] paramsList)
                => WorldManager.instance.EntrySubGame(gameid, entryMethod, paramsList);

            /// <summary>
            /// 卸载子游戏模块
            /// </summary>
            public static void UnloadSubGame()
                => WorldManager.instance.ExitSubGame();

            /// <summary>
            /// 添加全局摄像机
            /// </summary>
            /// <param name="sort"></param>
            /// <param name="camera"></param>
            public static void AddGlobalCamera(CameraSort sort, Camera camera)
                => AddGlobalCamera((int)sort, camera);

            /// <summary>
            /// 添加全局摄像机
            /// </summary>
            /// <param name="sort"></param>
            /// <param name="camera"></param>
            public static void AddGlobalCamera(int sort, Camera camera)
                => WorldManager.instance.AddCamera(sort, camera);

            /// <summary>
            /// 移除全局摄像机
            /// </summary>
            /// <param name="camera"></param>
            public static void RemoveGlobalCamera(Camera camera)
                => WorldManager.instance.RemoveCamera(camera);

            /// <summary>
            /// 获取指定的World,如果没有则创建
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="name"></param>
            /// <returns></returns>
            public static T CreateWorld<T>() where T : World
                => (T)CreateWorld(typeof(T));

            /// <summary>
            /// 获取指定的World,如果没有则创建
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="name"></param>
            /// <returns></returns>
            public static World CreateWorld(Type worldType)
                => WorldManager.instance.CreateWorld(worldType);

            /// <summary>
            /// 获取指定的World,如果没有则创建
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public static World GetWorld(string name)
                => WorldManager.instance.GetWorld(name);

            /// <summary>
            /// 获取指定的World,如果没有则创建
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="name"></param>
            /// <returns></returns>
            public static T GetWorld<T>() where T : World, new()
                => WorldManager.instance.GetWorld<T>();

            /// <summary>
            /// 关闭指定的World
            /// </summary>
            /// <param name="name"></param>
            public static void CloseWorld(string name)
                => WorldManager.instance.CloseWorld(name);
        }

        /// <summary>
        /// 游戏UI
        /// </summary>
        public sealed class Window
        {
            /// <summary>
            /// 获取或打开窗口
            /// </summary>
            /// <param name="layer"></param>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public static T GetOrOpen<T>(params object[] paramsList) where T : UIWindow, new()
                => (T)GetOrOpen(typeof(T), paramsList);

            /// <summary>
            /// 获取或打开窗口
            /// </summary>
            /// <param name="view"></param>
            /// <param name="layer"></param>
            /// <returns></returns>
            public static UIWindow GetOrOpen(Type view, params object[] paramsList)
                => WindowManager.instance.GetOrOpen(view, paramsList);

            /// <summary>
            /// 异步创建界面
            /// </summary>
            /// <param name="paramsList"></param>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public static Runnable<T> GetOrOpenAsync<T>(params object[] paramsList) where T : UIWindow
                => WindowManager.instance.GetOrOpenAsync<T>(paramsList);

            /// <summary>
            /// 异步创建界面
            /// </summary>
            /// <param name="viewType"></param>
            /// <param name="paramsList"></param>
            /// <returns></returns>
            public static Runnable<UIWindow> GetOrOpenAsync(Type viewType, params object[] paramsList)
                => WindowManager.instance.GetOrOpenAsync(viewType, paramsList);

            /// <summary>
            /// 获取指定的窗口
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public static UIWindow GetView<T>() where T : UIWindow
                => GetView(typeof(T));

            /// <summary>
            /// 获取指定的窗口
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public static UIWindow GetView(Type viewType)
                => WindowManager.instance.GetUIView(viewType);

            /// <summary>
            /// 关闭指定的窗口
            /// </summary>
            /// <typeparam name="T"></typeparam>
            public static void CloseView<T>() where T : UIWindow
                => CloseView(typeof(T));

            /// <summary>
            /// 关闭指定的窗口
            /// </summary>
            /// <param name="name"></param>
            public static void CloseView(Type view)
                => WindowManager.instance.RemoveUIView(view);

            /// <summary>
            /// 清理所有窗口
            /// </summary>
            public static void ClearView()
                => WindowManager.instance.ClearAll();

            /// <summary>
            /// 小提示框
            /// </summary>
            /// <param name="msg"></param>
            public static void Toast(string msg)
                => Window.GetOrOpen<Toast>().SetString(msg);

            /// <summary>
            /// 消息弹窗
            /// </summary>
            /// <param name="msg"></param>
            /// <param name="ok"></param>
            /// <param name="cancle"></param>
            public static void MsgBox(string msg)
                => MsgBox("Tips", msg, () => { CloseView<MsgBox>(); });

            /// <summary>
            /// 消息弹窗
            /// </summary>
            /// <param name="msg"></param>
            /// <param name="ok"></param>
            /// <param name="cancle"></param>
            public static void MsgBox(string msg, Action ok, Action cancle = null)
                => MsgBox("Tips", msg, ok, cancle);

            /// <summary>
            /// 消息弹窗
            /// </summary>
            /// <param name="title"></param>
            /// <param name="msg"></param>
            /// <param name="ok"></param>
            /// <param name="cancle"></param>
            public static void MsgBox(string title, string msg, Action ok, Action cancle = null)
                => GetOrOpen<MsgBox>().SetMsgBox(title, msg, ok, cancle);

            /// <summary>
            /// 等待提示框
            /// </summary>
            /// <param name="msg">提示消息</param>
            public static void Wait(string msg)
                => Wait(msg, -1, null);

            /// <summary>
            /// 等待提示框
            /// </summary>
            /// <param name="msg">提示消息</param>
            public static void Wait(string msg, float time)
                => Wait(msg, time, null);

            /// <summary>
            /// 等待提示框
            /// </summary>
            /// <param name="msg">提示消息</param>
            /// <param name="timeout">超时</param>
            public static void Wait(string msg, float timeout, Action callback)
                => GetOrOpen<Wait>().SetWait(msg, timeout, callback);

            /// <summary>
            /// 关闭等待界面
            /// </summary>
            public static void CloseWait()
                => CloseView<Wait>();
        }

        /// <summary>
        /// 文件管理
        /// </summary>
        public sealed class File
        {
            /// <summary>
            /// 打开文件选择窗口
            /// </summary>
            public static void OpenFileWindow()
                => VFSManager.instance.OpenFileWindow(string.Empty);

            /// <summary>
            /// 是否存在文件
            /// </summary>
            /// <param name="fileName"></param>
            /// <returns></returns>
            public static bool Exists(string fileName, uint version = 0, uint crc = 0)
                => VFSManager.instance.Exists(fileName.ToLower(), version, crc);

            /// <summary>
            /// 读取文件数据
            /// </summary>
            /// <param name="path"></param>
            /// <returns></returns>
            public static byte[] ReadData(string fileName, uint version = 0, uint crc = 0)
                => VFSManager.instance.ReadData(fileName.ToLower(), version, crc);

            /// <summary>
            /// 异步读取数据
            /// </summary>
            /// <param name="fileName"></param>
            /// <returns></returns>
            public static Runnable<byte[]> ReadDataAsync(string fileName, uint version = 0, uint crc = 0)
                => VFSManager.instance.ReadDataAsync(fileName.ToLower(), version, crc);

            /// <summary>
            /// 写入数据
            /// </summary>
            /// <param name="fileName"></param>
            /// <param name="bytes"></param>
            public static void WriterData(string fileName, byte[] bytes, uint version = 0, uint crc = 0)
                => VFSManager.instance.WriterData(fileName.ToLower(), bytes, version, crc);

            /// <summary>
            /// 异步写入数据
            /// </summary>
            /// <param name="fileName"></param>
            /// <param name="bytes"></param>
            /// <returns></returns>
            public static Runnable WriteDataAsync(string fileName, byte[] bytes, uint version = 0, uint crc = 0)
                => VFSManager.instance.WriteDataAsync(fileName.ToLower(), bytes, version, crc);
        }

        /// <summary>
        /// Web网络服务
        /// </summary>
        public sealed class Web
        {
            public static WebRequest UploadData(string url, byte[] bytes)
                => WebService.CreateRequest(url, WebMethod.PUT).UploadData(bytes);

            public static Runnable<byte[]> DownloadData(string url)
                => WebService.DownloadAssetBytes(url);

            public static Runnable<string> Post(string url, string body, string header)
                => WebService.Post(url, body, header);

            public static Runnable<string> Get(string url, string header)
                => WebService.Get(url, header);

            public static WebRequest CreateRequest(string uri, WebMethod method)
                => WebService.CreateRequest(uri, method);

            public static void POST(string url, object data, Action<Runnable<string>> callback)
                => CreateRequest(url, WebMethod.POST).UploadData(data).OnStart().Execute(callback);

            public static void POST(string url, object data, Dictionary<string, string> header, Action<Runnable<string>> callback)
                => CreateRequest(url, WebMethod.POST).UploadData(data).SetHeadder(header).OnStart().Execute(callback);
        }

        public sealed class Network
        {
            public static async Task<WebSocket> OnConnectWebSocket<T>(string name, string url, params IChannelHandler[] handlers) where T : INetworkSerialized
                => await NetManager.instance.OnConnectWebSocket<T>(name, url, handlers);

            public static async Task<TCPChannel> OnConnectTcpSocket<T>(string name, string address, ushort port, params IChannelHandler[] handlers) where T : INetworkSerialized
                => await NetManager.instance.OnConnectTcpSocket<T>(name, address, port, handlers);

            public static async Task<KCPChannel> OnConnectKcpSocket<T>(string name, int cid, string address, ushort port, params IChannelHandler[] handlers) where T : INetworkSerialized
                => await NetManager.instance.OnConnectKcpSocket<T>(name, cid, address, port, handlers);

            public static async Task CloseConnect(string name)
                => await NetManager.instance.CloseConnect(name);

            public static IChannel GetChannel(string name)
                => NetManager.instance.GetChannel(name);
        }

        /// <summary>
        /// 日志
        /// </summary>
        public sealed class Console
        {
            /// <summary>
            /// 输出日志
            /// </summary>
            /// <param name="message"></param>
            public static void WriteLine(object message)
                => Debug.Log($"[INFO] {message}");

            /// <summary>
            /// 输出日志
            /// </summary>
            /// <param name="message"></param>
            public static void WriteLine(params object[] message)
                => WriteLine(string.Join(",", message));

            /// <summary>
            /// 输出日志
            /// </summary>
            /// <param name="format"></param>
            /// <param name="args"></param>
            public static void WriteLineFormat(string format, params object[] args)
                => WriteLine(string.Format(format, args));

            /// <summary>
            /// 输出错误日志
            /// </summary>
            /// <param name="message"></param>
            public static void WriteError(object message)
                => Debug.LogError($"[ERROR] {message}");

            /// <summary>
            /// 输出错误日志
            /// </summary>
            /// <param name="message"></param>
            public static void WriteError(params object[] message)
                => WriteError(string.Join(",", message));

            /// <summary>
            /// 输出错误日志
            /// </summary>
            /// <param name="format"></param>
            /// <param name="args"></param>
            public static void WriteErrorFormat(string format, params object[] args)
                => WriteError(string.Format(format, args));


            /// <summary>
            /// 输出错误日志
            /// </summary>
            /// <param name="message"></param>
            public static void WriterWarning(object message)
                => Debug.LogWarning($"[WARNING] {message}");

            /// <summary>
            /// 输出错误日志
            /// </summary>
            /// <param name="message"></param>
            public static void WriterWarning(params object[] message)
                => WriteError(string.Join(",", message));

            /// <summary>
            /// 输出错误日志
            /// </summary>
            /// <param name="format"></param>
            /// <param name="args"></param>
            public static void WriterWarningFormat(string format, params object[] args)
                => WriteError(string.Format(format, args));
        }

        /// <summary>
        /// 资源管理
        /// </summary>
        public sealed class Resource
        {
            public static LoadingBundleRunnable PreLoadBundle(string module)
                => ResourceManager.instance.PreLoadBundle(module);

            public static SceneLoadRunnable LoadScene(string name)
                => ResourceManager.instance.LoadSceneAsync(name);

            /// <summary>
            /// 加载资源
            /// </summary>
            /// <param name="assetName"></param>
            /// <returns></returns>
            public static Object LoadAsset(string url, GameObject bind = null)
                => LoadAsset<Object>(url, bind);

            /// <summary>
            /// 加载资源
            /// </summary>
            /// <param name="assetName"></param>
            /// <returns></returns>
            public static Runnable<Object> LoadAssetAsync(string url, GameObject bind = null)
                => LoadAssetAsync<Object>(url, bind);

            /// <summary>
            /// 加载资源
            /// </summary>
            /// <param name="assetName"></param>
            /// <returns></returns>
            public static T LoadAsset<T>(string url, GameObject bind = null) where T : Object
                => ResourceManager.instance.LoadAsset<T>(url, bind);

            /// <summary>
            /// 加载资源
            /// </summary>
            /// <param name="assetName"></param>
            /// <returns></returns>
            public static Runnable<T> LoadAssetAsync<T>(string url, GameObject bind = null) where T : Object
                => ResourceManager.instance.LoadAssetAsync<T>(url, bind);

            /// <summary>
            /// 加载资源
            /// </summary>
            /// <param name="assetName"></param>
            /// <returns></returns>
            public static Runnable<T> LoadNetworkAssetAsync<T>(string url, string name = "", GameObject bind = null, uint version = 0, uint crc = 0) where T : Object
                => ResourceManager.instance.LoadNetworkAsync<T>(url, name, bind, version, crc);

            /// <summary>
            /// 加载网络资源包
            /// </summary>
            /// <param name="url"></param>
            /// <param name="version"></param>
            /// <param name="crc"></param>
            /// <returns></returns>
            public static Runnable LoadNetworkBundleAsync(string url, uint version = 0, uint crc = 0)
                => ResourceManager.instance.LoadNetworkBundleAsync(url, version, crc);

            /// <summary>
            /// 回收资源
            /// </summary>
            /// <param name="context"></param>
            public static void Release(Object target) => ResourceManager.instance.Release(target);

            /// <summary>
            /// 检查资源更新
            /// </summary>
            /// <param name="bucket"></param>
            /// <returns></returns>
            public static CheckUpdateRunnable CheckUpdateAssetList(string module)
                => ResourceManager.instance.CheckUpdateAssetList(module);

            /// <summary>
            /// 开始更新资源
            /// </summary>
            /// <param name="bucket"></param>
            /// <param name="update"></param>
            /// <returns></returns>
            public static UpdateResourceRunnable UpdateModuleAssetList(List<PackageInfo> update)
                => ResourceManager.instance.UpdateModuleAssetList(update);
        }

        /// <summary>
        /// 事件管理
        /// </summary>
        public sealed class Events
        {
            /// <summary>
            /// 通知事件
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="evtData"></param>
            public static void Notify(string evtName, object evtData = null)
                => EventSystem.instance.NotiflyEvent(evtName, evtData);

            /// <summary>
            /// 通知事件
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="evtData"></param>
            public static void Notify<T>(T argsData) where T : EventArgsData<T>
                => EventSystem.instance.NotiflyEvent(argsData.name, argsData);

            /// <summary>
            /// 清理所有订阅
            /// </summary>
            public static void Clear()
                => EventSystem.instance.Dispose();

            /// <summary>
            /// 清理所有订阅
            /// </summary>
            public static void Clear(string evtName)
                => EventSystem.instance.Clear(evtName);

            /// <summary>
            /// 注册只触发一次的回调
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="callback"></param>
            public static void Once(string evtName, Action<object> callback)
                => EventSystem.instance.Register(evtName, true, callback);

            /// <summary>
            /// 注册事件回调
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="callback"></param>
            public static void Register(string evtName, Action<object> callback)
                => EventSystem.instance.Register(evtName, true, callback);

            /// <summary>
            /// 移除事件回调
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="callback"></param>
            public static void Unregister(string evtName, Action<object> callback)
                => EventSystem.instance.Unregister(evtName, callback);

            /// <summary>
            /// 注册只触发一次的回调
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="callback"></param>
            public static void Once(string evtName, Action callback)
                => EventSystem.instance.Register(evtName, true, args => { callback(); });

            /// <summary>
            /// 注册事件回调
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="callback"></param>
            public static void Register(string evtName, Action callback)
                => EventSystem.instance.Register(evtName, true, args => { callback(); });

            /// <summary>
            /// 注册事件回调
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="callback"></param>
            public static void Register<T>(Action callback) where T : EventArgsData<T>
                => EventSystem.instance.Register(typeof(T).Name, true, args => { callback(); });

            /// <summary>
            /// 注册事件回调
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="callback"></param>
            public static void Register<T>(Action<T> callback) where T : EventArgsData<T>
                => EventSystem.instance.Register(typeof(T).Name, true, args => callback((T)args));

            /// <summary>
            /// 移除事件回调
            /// </summary>
            /// <param name="evtName"></param>
            /// <param name="callback"></param>
            public static void Unregister(string evtName, Action callback)
                => EventSystem.instance.Unregister(evtName, args => { callback(); });

            /// <summary>
            /// 订阅事件分发
            /// </summary>
            /// <param name="callback"></param>
            public static void Subscribe<T>() where T : IEventHandle
                => Subscribe(typeof(T));

            /// <summary>
            /// 移除事件分发订阅
            /// </summary>
            /// <param name="callback"></param>
            public static void Unsubscribe<T>() where T : IEventHandle
                => Unsubscribe(typeof(T));

            /// <summary>
            /// 订阅事件分发
            /// </summary>
            /// <param name="callback"></param>
            public static void Subscribe(Type type)
                => EventSystem.instance.Subscribe(type);

            /// <summary>
            /// 移除事件分发订阅
            /// </summary>
            /// <param name="callback"></param>
            public static void Unsubscribe(Type type)
                => EventSystem.instance.Unsubscribe(type);
        }

        /// <summary>
        /// 任务管理器
        /// </summary>
        public sealed class Running
        {
            /// <summary>
            /// 获取或创建任务
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="result"></param>
            /// <returns>true:表示任务已存在 false:表示为新建任务</returns>
            public static bool TryGetOrCreate<T>(string key, out T result) where T : IRunning
                => RunnableManager.instance.TryGetOrCreate<T>(key, out result);

            public static Runnable<T> FromResult<T>(T args)
                => RunnableManager.instance.FromCompleted(args);

            public static Runnable<T> FromException<T>(Exception ex)
                => RunnableManager.instance.FromException<T>(ex);

            public static Runnable FromResult(object args)
                => RunnableManager.instance.FromCompleted(args);

            public static Runnable FromException(Exception ex)
                => RunnableManager.instance.FromCompleted(ex);

            public static Runnable Combine(params Runnable[] runnables) => null;
        }

        /// <summary>
        /// 扩展
        /// </summary>
        public sealed class Tools
        {
            public static ScheduleCancelToken Scheduled(float time, Action action)
                => UnityHandler.Scheduled(time, action);

            public static void AddUpdate(Action onUpdateCallback)
                => UnityHandler.AddUpdate(onUpdateCallback);

            public static void RemoveCallback(Action callback)
                => UnityHandler.RemoveCallback(callback);

            public static void AddFixedUpdate(Action callback)
                => UnityHandler.AddFixedUpdate(callback);

            public static Coroutine StartCoroutine(IEnumerator enumerator)
                => UnityHandler.OnStartCoroutine(enumerator);

            public static void StopCoroutine(Coroutine enumerator)
                => UnityHandler.OnStopCoroutine(enumerator);

            public static void RegisterConroutineStartu(Action<IEnumerator> startup, Action<Coroutine> stop)
                => UnityHandler.RegisterConroutineStartu(startup, stop);

            public static void ClearConroutineStartup()
                => UnityHandler.UnregisterConroutineStartu();

            public static void DestroyCallback(GameObject gameObject, Action action)
                => UnityHandler.ListenDestory(gameObject, action);

            public static void DestroyCallback<T>(GameObject gameObject, Action<T> action, T args)
                => UnityHandler.ListenDestory(gameObject, action, args);

            public static void Wait(float time, Action action)
                => UnityHandler.Wait(time, action);

            public static void WaitFrameEnd(Action action)
                => UnityHandler.WaitFrameEnd(action);

            public static ScheduleCancelToken Countdown(int time, int interval, bool isadd, Action<int> callback)
                => UnityHandler.Countdown(time, interval, isadd, callback);

            /// 如果启用 Behaviour，则在每一帧都将调用 LateUpdate
            public static void LateUpdate(Action action)
                => UnityHandler.AddLate(action);

            public static void UnityEventListener(GameObject gameObject, UnityEventNames eventNames, Action<object> callback)
                => UnityHandler.AddUnityEventListener(gameObject, eventNames, callback);

            public static void RunningInMainThread(Action action)
                => UnityHandler.RunningInMainThread(action);

            public static void RunningInMainThread<T>(Action<T> action, T args)
                => RunningInMainThread(() => { action(args); });

            public static string Sha256(string value)
                => value.Sha256();
        }

        public sealed class Avatar
        {
            /// <summary>
            /// 确认是否初始化
            /// </summary>
            /// <returns></returns>
            public static bool EnsureInitializedAvatarBuilded() => AvatarInstance.instance.EnsureAvatarInitialized();

            /// <summary>
            /// 确认资源组是否一致
            /// </summary>
            /// <param name="groupName"></param>
            /// <returns></returns>
            public static bool EnsureAvatarBuildedGroupName(string groupName) => AvatarInstance.instance.EnsureAvatarBuildedGroupName(groupName);

            /// <summary>
            /// 初始化编辑器
            /// </summary>
            /// <param name="args">初始化参数</param>
            public static void Initialized(AvatarOptions args) => AvatarInstance.instance.Initialized(args);

            /// <summary>
            /// 清理部件
            /// </summary>
            /// <param name="element"></param>
            public static void ClearElement(int element) => AvatarInstance.instance.ClearElement(element);

            /// <summary>
            /// 将部位显示在视图中心
            /// </summary>
            public static void ShowInView(int element) => AvatarInstance.instance.ShowInView(element);

            /// <summary>
            /// 导出配置
            /// </summary>
            /// <param name="configName">保存的配置名</param>
            public static void ExportConfig(string configName) => AvatarInstance.instance.ExportConfig(configName);

            /// <summary>
            /// 获取部件数据
            /// </summary>
            /// <param name="element">部位枚举</param>
            public static ElementData GetElementData(int element) => AvatarInstance.instance.GetElementData(element);

            /// <summary>
            /// 获取部件数据
            /// </summary>
            /// <param name="element">部位枚举</param>
            public static ElementComponent GetElementComponent(int element) => AvatarInstance.instance.GetElementComponent(element);

            /// <summary>
            /// 导入配置
            /// </summary>
            /// <param name="config">配置数据</param>
            public static void ImportConfig(string config) => AvatarInstance.instance.ImportConfig(config);

            /// <summary>
            /// 设置部件模型
            /// </summary>
            /// <param name="elementData">部位数据</param>
            public static void SetElementData(List<ElementData> elementData) => AvatarInstance.instance.SetElementData(elementData);

            /// <summary>
            /// 设置部件模型
            /// </summary>
            /// <param name="elementData">部位数据</param>
            public static void SetElementData(ParallelRunnable executed, ElementData element) => AvatarInstance.instance.SetElementData(executed, element);

            /// <summary>
            /// 合并Avatar
            /// </summary>
            public static void Combine() => AvatarInstance.instance.Combine();

            /// <summary>
            /// 上传部件资源
            /// </summary>
            /// <param name="element">部件位置</param>
            /// <param name="fileDataString">文件数据</param>
            public static void UploadAsset(int element) => AvatarInstance.instance.UploadAsset(element);

            /// <summary>
            /// 预览
            /// </summary>
            /// <param name="element">部位枚举</param>
            public static void PreviewAsset(int element) => AvatarInstance.instance.PreviewAsset(element);

            /// <summary>
            /// 隐藏部位
            /// </summary>
            /// <param name="element"></param>
            public static void DisableElement(int element) => AvatarInstance.instance.DisableElement(element);

            /// <summary>
            /// 显示部位
            /// </summary>
            /// <param name="element"></param>
            public static void EnableElement(int element) => AvatarInstance.instance.EnableElement(element);

            /// <summary>
            /// 播放动画
            /// </summary>
            /// <param name="name"></param>
            public static void PlayAction(string name) => AvatarInstance.instance.PlayAction(name);

            /// <summary>
            /// 播放表情动画
            /// </summary>
            /// <param name="emotionData"></param>
            public static void PlayFaceAction(Dictionary<int, float> emotionData) => AvatarInstance.instance.PlayFaceAction(emotionData);
        }

        public sealed class Drawing
        {
            /// <summary>
            /// 部件涂鸦
            /// </summary>
            /// <param name="element"></param>
            public static void ElementGraffiti(string data) => ZyGame.Drawing.DrawingInstance.instance.ElementGraffiti(data);


            /// <summary>
            /// 退出涂鸦
            /// </summary>
            public static void ExitGraffiti() => ZyGame.Drawing.DrawingInstance.instance.ExitGraffiti();

            /// <summary>
            /// 保存涂鸦数据
            /// </summary>
            /// <param name="name">文件名,如果文件为空则不保存数据</param>
            public static void Save(string name) => ZyGame.Drawing.DrawingInstance.instance.Save(name);

            /// <summary>
            /// 发布涂鸦
            /// </summary>
            public static void PublishGraffiti(string name) => ZyGame.Drawing.DrawingInstance.instance.PublishGraffiti(name);

            /// <summary>
            /// 设置画笔
            /// </summary>
            /// <param name="brush">1:钢笔 2:刷子 3:橡皮檫 4:拖动</param>
            public static void SetPaintbrushType(int brush) => ZyGame.Drawing.DrawingInstance.instance.SetPaintbrushType(brush);

            /// <summary>
            /// 设置画笔颜色
            /// </summary>
            /// <param name="hexadecimal">颜色值</param>
            public static void SetPaintbrushColor(string hexadecimal) => ZyGame.Drawing.DrawingInstance.instance.SetPaintbrushColor(hexadecimal);

            /// <summary>
            /// 设置画笔大小
            /// </summary>
            /// <param name="width"></param>
            public static void SetPaintbrushWidth(float width) => ZyGame.Drawing.DrawingInstance.instance.SetPaintbrushWidth(width);

            /// <summary>
            /// 在当前选中的图层中导入涂鸦图片
            /// </summary>
            public static void ImportGraffitiTexture() => ZyGame.Drawing.DrawingInstance.instance.ImportGraffitiTexture();

            /// <summary>
            /// 新建图层
            /// </summary>
            /// <param name="name">图层名</param>
            public static void NewLayer(string name) => ZyGame.Drawing.DrawingInstance.instance.NewLayer(name);

            /// <summary>
            /// 选中图层
            /// </summary>
            /// <param name="name">要选中的图层名</param>
            public static void SelectionLayer(string name) => ZyGame.Drawing.DrawingInstance.instance.SelectionLayer(name);

            /// <summary>
            /// 删除选中图层
            /// </summary>
            public static void DeleteLayer() => ZyGame.Drawing.DrawingInstance.instance.DeleteLayer();

            /// <summary>
            /// 设置选中图层透明度
            /// </summary>
            /// <param name="alpha">透明度 </param>
            public static void SetLayerAlpha(float alpha) => ZyGame.Drawing.DrawingInstance.instance.SetLayerAlpha(alpha);

            /// <summary>
            /// 设置图层缩放大小
            /// </summary>
            /// <param name="size"></param>
            public static void SetLayerSize(float size) => ZyGame.Drawing.DrawingInstance.instance.SetLayerSize(size);

            /// <summary>
            /// 撤销
            /// </summary>
            /// <param name="isBackup">0:后退，1:前进</param>
            public static void Undo(int isBackup) => ZyGame.Drawing.DrawingInstance.instance.Undo(isBackup);

            /// <summary>
            /// 设置图层排序
            /// </summary>
            /// <param name="index"></param>
            public static void SetSort(int index) => ZyGame.Drawing.DrawingInstance.instance.SetSort(index);
        }
    }
}